#include "Platform.h"

#include "MsgMgr.h"
#include "Log.h"
#include "LoginApp.h"
#include "TimeUtil.h"
#include "ClientApp.h"

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

CPlatform::CPlatform()
{
}


CPlatform::~CPlatform()
{
}

bool CPlatform::Init()
{
    bool bFlag = CMsgMgr::Instance().Init();
    if (bFlag == false)
    {
        return false;
    }

    CMsgMgr::Instance().AddListen("127.0.0.1", 10812);

    CBaseApp *pBaseApp = NULL;

    pBaseApp = new CLoginApp();
    if (pBaseApp == NULL)
    {
        return false;
    }
    if (!pBaseApp->Init())
    {
        return false;
    }
    if (!AddApp(comm::ENM_MODULE_LOGIN, pBaseApp))
    {
        LOG_ERR("Add CLoginApp Fail.");
        return false;
    }

	pBaseApp = new CClientApp();
	if (pBaseApp == NULL)
	{
		return false;
	}
	if (!pBaseApp->Init())
	{
		return false;
	}
	if (!AddApp(comm::ENM_MODULE_LOGIN, pBaseApp))
	{
		LOG_ERR("Add CLoginApp Fail.");
		return false;
	}

    return true;
}

int CPlatform::Run(int argc, char** argv)
{
    int iStep = 0;
    int iCount = 0;
    //while (true)
    {
		CTimeUtil::SetCurTime();
		//CScheduleMgr::Instance().HandTick();
        iCount = CMsgMgr::Instance().Polling(1);
        if (0 < iCount)
        {
#ifdef _WIN32
            Sleep(1);
#else
            usleep(1);
#endif
        }
    }
    return 0;
}

int CPlatform::Handle(const comm::Head &pbHead, const std::string &pszBody)
{
    comm::EnmModuleCmd eModule = CMsgMgr::Instance().GetModuleFromCmd( pbHead.cmd());

    pair<CmdMultiMap::iterator, CmdMultiMap::iterator> pairMMap = m_multimapModuleRoute.equal_range(eModule);

    if (pairMMap.first == pairMMap.second)
    {
        LOG_ERR("Can't find module.ModuleRouteSize:%d Module:%d", (int)m_multimapModuleRoute.size(), eModule);
        return -1;
    }

    while (pairMMap.first != pairMMap.second)
    {
        CBaseApp *pBaseApp = pairMMap.first->second;
        ++pairMMap.first;

        if (pBaseApp == NULL)
        {
            LOG_ERR("BaseApp is NULL.Module:%d", eModule);
            continue;
        }

        int iCmd = CMsgMgr::Instance().GetEnmCmd(pbHead.cmd());
        CmdRouteMap &mapCmdRouteMap = pBaseApp->GetCmdRounteMap();

        CmdRouteMap::iterator itMap = mapCmdRouteMap.find(iCmd);

        if (itMap == mapCmdRouteMap.end())
        {
            LOG_ERR("Can't Find Cmd Handle.CmdRounteSize:%d Module:%d Cmd:%d",(int)mapCmdRouteMap.size(), eModule, iCmd);
            continue;
        }

        google::protobuf::Message* pMessage = itMap->second;
        if (pMessage == NULL)
        {
            LOG_ERR("Message is NULL.Module:%d Cmd:%d", eModule, iCmd);
            continue;
        }

        if (!pMessage->ParseFromArray(pszBody.c_str(), pszBody.size()))
        {
            LOG_ERR("Parse Packet Body Fail.Cmd:%d Len:%d", iCmd, (int)pszBody.size());
            continue;
        }
        pBaseApp->HandleMessage(pbHead, *pMessage);
    }

    return 0;
}

bool CPlatform::AddApp(comm::EnmModuleCmd eModule, CBaseApp *pBaseApp)
{
    if (pBaseApp == NULL)
    {
        return false;
    }
    m_multimapModuleRoute.insert(make_pair(eModule, pBaseApp));
    
    return true;
}
